package cn.itsource.pethome.order.service.impl;

import cn.itsource.pethome.basic.service.impl.BaseServiceImpl;
import cn.itsource.pethome.order.domain.OrderAddress;
import cn.itsource.pethome.order.domain.OrderProduct;
import cn.itsource.pethome.order.domain.OrderProductDetail;
import cn.itsource.pethome.order.mapper.OrderProductMapper;
import cn.itsource.pethome.order.service.IOrderAddressService;
import cn.itsource.pethome.order.service.IOrderProductDetailService;
import cn.itsource.pethome.order.service.IOrderProductService;
import cn.itsource.pethome.org.domain.Shop;
import cn.itsource.pethome.org.service.IShopService;
import cn.itsource.pethome.pay.domain.PayBill;
import cn.itsource.pethome.pay.domain.PayConstants;
import cn.itsource.pethome.pay.service.IPayBillService;
import cn.itsource.pethome.product.domain.Product;
import cn.itsource.pethome.product.service.IProductService;
import cn.itsource.pethome.quartz.MainJob;
import cn.itsource.pethome.quartz.domain.JobTypeConsts;
import cn.itsource.pethome.quartz.domain.QuartzJobInfo;
import cn.itsource.pethome.quartz.service.IQuartzService;
import cn.itsource.pethome.quartz.utils.QuartzUtils;
import cn.itsource.pethome.user.domain.User;
import cn.itsource.pethome.user.domain.UserAddress;
import cn.itsource.pethome.user.service.IUserAddressService;
import cn.itsource.pethome.utils.AjaxResult;
import cn.itsource.pethome.utils.CodeGenerateUtils;
import cn.itsource.pethome.utils.DistanceUtil;
import org.quartz.Scheduler;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderProductServiceImpl extends BaseServiceImpl<OrderProduct> implements IOrderProductService {

    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private IUserAddressService userAddressService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private IProductService productService;
    @Autowired
    private IOrderProductDetailService orderProductDetailService;
    @Autowired
    private IOrderAddressService orderAddressService;
    @Autowired
    private IPayBillService payBillService;
    @Autowired
    private IQuartzService quartzService;

    @Override
    public OrderProduct loadByOrderSn(String orderSn) {
        return orderProductMapper.loadByOrderSn(orderSn);
    }

    @Override
    public AjaxResult createOrder(Map<String, String> map, User user) {
        try {
            //1. 组装需要的数据
            String address_id = map.get("address_id");
            UserAddress userAddress = userAddressService.loadById(Long.valueOf(address_id));
            String productId = map.get("productId");
            Product product = productService.loadById(Long.valueOf(productId));
            OrderProduct orderProduct = createOrderProduct(userAddress, product, user);
            System.out.println(map.get("payway"));
            orderProduct.setPayway(map.get("payway"));
            //存入数据库并返回主键
            orderProductMapper.save(orderProduct);

            //2. 将数据存入t_product_detail表
            OrderProductDetail orderProductDetail = cteateOrderDetail(product);
            orderProductDetail.setOrder(orderProduct);
            orderProductDetailService.save(orderProductDetail);

            //3. 将数据存入t_order_address表中
            OrderAddress orderAddress = userAddressToOrderAddress(userAddress);
            orderAddress.setOrderSn(orderProduct.getOrderSn());
            orderAddress.setOrder(orderProduct);
            orderAddressService.save(orderAddress);

            //3.1 生成订单时，同时生成一个定时器任务，在支付一直未完成时，将订单状态改为-1（已取消）
            //组装定时器需要的参数QuartzJobInfo
            QuartzJobInfo quartzJobInfo = new QuartzJobInfo();
            quartzJobInfo.setType(JobTypeConsts.WAIT_PRODUCT_ORDER_PAY_CANCEL_JOB);
            quartzJobInfo.setJobName("product_"+orderProduct.getOrderSn());
            quartzJobInfo.setFireDate(orderProduct.getLastPayTime());
            Map<String,Object> quartzMap = new HashMap<>();
            quartzMap.put("orderSn", orderProduct.getOrderSn());
            quartzJobInfo.setParams(quartzMap);
            quartzService.addJob(quartzJobInfo);

            //4. 生成系统订单的同时，生成一个支付订单
            PayBill payBill = createPayBill(orderProduct, user);
            payBillService.save(payBill);

            //5. 生成订单后，向支付宝发起请求
            String resultUrl = payBillService.goPay(payBill);

            return AjaxResult.me().setResultObj(resultUrl);
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return new AjaxResult("网络延迟，请稍后再试");
        }
    }


    private PayBill createPayBill(OrderProduct orderProduct, User user){
        PayBill payBill = new PayBill();
//        digest money state lastPayTime payChannel createTime updateTime user_id
//        nickName unionPaySn businessType businessKey shop_id orderSn
//        组装数据时还差unionPaySn，updateTime，后面从支付宝获取
        payBill.setDigest(orderProduct.getDigest());
        payBill.setMoney(orderProduct.getPrice());
        payBill.setState(0);
        payBill.setLastPayTime(orderProduct.getLastPayTime());
        // payChannel  0 余额 1 支付宝 2 微信 3 银联
        payBill.setPayChannel(1);
        payBill.setCreateTime(new Date());
        payBill.setUser_id(user.getId());
        payBill.setBusinessType(PayConstants.BUSINESSTYPE_PRODUCT);
        payBill.setBusinessKey(orderProduct.getId());
        payBill.setShop_id(orderProduct.getShop().getId());
        payBill.setOrderSn(orderProduct.getOrderSn());
        return payBill;
    }

    private OrderProduct createOrderProduct(UserAddress userAddress,Product product,User user){
        OrderProduct orderProduct = new OrderProduct();
        orderProduct.setDigest("[服务订单]购买"+product.getName());
        orderProduct.setLastPayTime(new Date(System.currentTimeMillis()+1000*60));
        orderProduct.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        orderProduct.setPrice(product.getSaleprice());
        orderProduct.setProduct(product);
        List<Shop> shops = shopService.loadAll();
        Shop shop = DistanceUtil.getNearestShop(DistanceUtil.getPoint(userAddress.getFullAddress()), shops);
        orderProduct.setShop(shop);
        orderProduct.setState(0);
        orderProduct.setUser(user);
        return orderProduct;
    }

    private OrderProductDetail cteateOrderDetail(Product product){
        OrderProductDetail orderProductDetail = new OrderProductDetail();
        BeanUtils.copyProperties(product, orderProductDetail);
        return orderProductDetail;
    }

    private OrderAddress userAddressToOrderAddress(UserAddress userAddress){
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        return orderAddress;
    }

}
